import 'dart:io';

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_dio/user_info.dart';
import 'package:flutter_dio/utils/dio_manager.dart';
import 'package:image_picker/image_picker.dart';
import 'package:path_provider/path_provider.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Dio Demo'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  String resultMessage = "";

  UserInfo? _userInfo;
  List<UserInfo> userInfoList = [];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ElevatedButton(
                onPressed: () {
                  getFunction();
                },
                child: const Text("Dio Get 请求")),
            ElevatedButton(
                onPressed: () {
                  getUserListFunction();
                },
                child: const Text("JSON 数据解析")),
            ElevatedButton(
                onPressed: () {}, child: const Text("Dio Get 请求 传参数")),
            ElevatedButton(
                onPressed: () {
                  regesterUserFunction();
                },
                child: const Text("Dio Post 请求 ")),
            ElevatedButton(
                onPressed: () {}, child: const Text("Dio Post 请求 传参数")),
            ElevatedButton(
                onPressed: () {}, child: const Text("Dio 请求头 拦截器设置")),
            ElevatedButton(
                onPressed: () {
                  testDioManager();
                },
                child: const Text("Dio 封装请求")),
            ElevatedButton(
                onPressed: () {
                  fileUploadFunction();
                },
                child: const Text("Dio 文件上传")),
            Text("请求的数据是:$resultMessage"),
            buildUserInfoWidget(),
            buildUserListWidget(),
            buildImageWidget(),
          ],
        ),
      ),
    );
  }

  buildImageWidget() {
    if (_imageUrl == null) {
      return SizedBox(
        child: Text(progressStr ?? ""),
      );
    }
    return Image.network(
      _imageUrl!,
      width: 100,
      height: 100,
    );
  }

  buildUserListWidget() {
    if (userInfoList.isEmpty) {
      return const SizedBox();
    }
    List<Widget> widgetList = [];
    for (int i = 0; i < userInfoList.length; i++) {
      UserInfo itemUserInfo = userInfoList[i];
      widgetList.add(
        Container(
          margin: const EdgeInsets.only(
            right: 10,
          ),
          color: Colors.blue,
          child: Text(
            "姓名：${itemUserInfo.userName} 年龄: ${itemUserInfo.userAge}",
            style: const TextStyle(color: Colors.white),
          ),
        ),
      );
    }

    return Wrap(
      children: widgetList,
    );
  }

  buildListView() {
    if (userInfoList.isEmpty) {
      return const SizedBox();
    }
    return ListView.builder(
      itemBuilder: (BuildContext context, int index) {
        UserInfo itemUserInfo = userInfoList[index];
        return Container(
          margin: const EdgeInsets.only(
            right: 10,
          ),
          color: Colors.blue,
          child: Text(
            "姓名：${itemUserInfo.userName} 年龄: ${itemUserInfo.userAge}",
            style: const TextStyle(color: Colors.white),
          ),
        );
      },
    );
  }

  buildUserInfoWidget() {
    if (_userInfo == null) {
      return const SizedBox();
    }
    return Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        Text("姓名 ：${_userInfo!.userName}"),
        Text("年龄 ：${_userInfo!.userAge}"),
        Text("工作 ：${_userInfo!.worke ?? "暂无工作信息"}"),
      ],
    );
  }

  ///dio 封装的工具类
  void testDioManager() async {
    String url = "http://192.168.0.195:8899/user/info";
    //传参数 方式二
    Map<String, dynamic> queryParameters = {"userName": "张三"};
    //发起get请求
    HttpResponse httpResponse = await DioManager.instance
        .getRequest(path: url, queryParameters: queryParameters);
    //请求完成
    if (httpResponse.isOk()) {
      //请求成功
      if (httpResponse.data != null) {
        //请求成功有数据
        UserInfo userInfo = UserInfo.fromMap(httpResponse.data);
        //刷新页面
        debugPrint("解析用户信息成功 ${userInfo.userName}");
      } else {
        debugPrint("请求成功 暂无用户信息");
      }
    } else {
      //请求失败
      debugPrint(
          "请求失败 ${httpResponse.statusCode}  ${httpResponse.statusMessage}");
    }
  }

  /// async await 组合  异步处理 Map 数据解析
  CancelToken? _cancelToken1;

  /// 基本请求、传参方式、取消请求、接收数据进度、JSON数据解析
  getFunction() async {
    debugPrint("get 请求");
    //传参数 方式一
    String url = "http://192.168.1.24:8899/user/info?userName=张三";

    //传参数 方式二
    Map<String, dynamic> queryParameters = Map();
    queryParameters["userName"] = "张三";

    //取消网络请求使用
    //页面退出的时候使用
    if (_cancelToken1 != null && !_cancelToken1!.isCancelled) {
      _cancelToken1!.cancel();
    }
    _cancelToken1 = CancelToken();

    //第一步 创建 Dio
    Dio dio = Dio();
    //第二步 发起请求
    Response response = await dio.get(url, cancelToken: _cancelToken1,
        onReceiveProgress: (int count, int total) {
      debugPrint("接收数据 $count / $total");
      //用来显示进度
    });
    dynamic result = response.data;
    int? statusCode = response.statusCode;
    String? statusMessage = response.statusMessage;
    if (statusCode != null && statusCode == 200) {
      // result 就是请求结果
      debugPrint("get 请求结果是 $result}");
      //JSON 解析数据
      String code = result["code"];
      String msg = result["msg"];
      dynamic data = result["data"];
      if (code == "OK") {
        debugPrint("请求成功");
        if (data != null) {
          if (data is Map) {
            debugPrint("data is Map");
            UserInfo userInfo = UserInfo.fromMap(data);
            debugPrint("data 解析成功 ${userInfo.userName}");
            _userInfo = userInfo;
          } else if (data is List) {
            debugPrint("data is List");
          }
        } else {
          //无数据的处理
        }
      } else {
        debugPrint("请求失败 : $code:$msg");
      }

      resultMessage = result.toString();
      setState(() {});
    } else {
      resultMessage = "网格请求错误 $statusCode $statusMessage";
      setState(() {});
    }
  }

  /// async await 组合  异步处理  List数据解析
  getUserListFunction() async {
    debugPrint("get 请求");
    String url = "http://192.168.1.24:8899/user/list";

    //第一步 创建 Dio
    Dio dio = Dio();
    //第二步 发起请求
    Response response = await dio.get(url);
    dynamic result = response.data;
    int? statusCode = response.statusCode;
    String? statusMessage = response.statusMessage;
    if (statusCode != null && statusCode == 200) {
      // result 就是请求结果
      debugPrint("get 请求结果是 $result}");
      //JSON 解析数据
      String code = result["code"];
      String msg = result["msg"];
      dynamic data = result["data"];
      if (code == "OK") {
        debugPrint("请求成功");
        if (data != null) {
          if (data is Map) {
            debugPrint("data is Map");
            UserInfo userInfo = UserInfo.fromMap(data);
            debugPrint("data 解析成功 ${userInfo.userName}");
            _userInfo = userInfo;
          } else if (data is List) {
            debugPrint("data is List");
            List<UserInfo> themList = [];
            List list = data;
            for (int i = 0; i < list.length; i++) {
              dynamic itemData = list[i];
              UserInfo userInfo = UserInfo.fromMap(itemData);
              themList.add(userInfo);
            }
            userInfoList = themList;
          }
        } else {
          //无数据的处理
        }
      } else {
        debugPrint("请求失败 : $code:$msg");
      }

      resultMessage = result.toString();
      setState(() {});
    } else {
      resultMessage = "网格请求错误 $statusCode $statusMessage";
      setState(() {});
    }
  }

  ///post 请求  提交json 数据 注册用户
  regesterUserFunction() async {
    //第一步
    Dio dio = Dio();
    String url = "http://192.168.1.24:8899/user/register";

    //第二步 组装数据
    Map<String, dynamic> data = Map();

    /*
    {
    "userName": "测试用户1",
    "userAge": 56
    }
     */
    data["userName"] = "测试用户1";
    data["userAge"] = 56;

    //第三步 发起请求
    Response response = await dio.post(url, data: data);

    //第四步 解析响应结果
    int? statusCode = response.statusCode;
    String? statusMessage = response.statusMessage;
    if (statusCode != null && statusCode == 200) {
      dynamic responseData = response.data;
      /*
            {
          "msg": "success",
          "code": "OK",
          "data": {
              "userId": 3,
              "userName": "测试用户1",
              "userAge": 56,
              "worke": null
          }
      }
       */
      String code = responseData["code"];
      String msg = responseData["msg"];
      if (code == "OK") {
        dynamic itemData = responseData["data"];
        if (itemData != null) {
          UserInfo userInfo = UserInfo.fromMap(itemData);
          _userInfo = userInfo;
        }
      } else {
        //请求失败的处理
        resultMessage = "请求失败 $code  $msg";
      }
    } else {
      //请求失败的处理
      resultMessage = "网络错误 $statusCode $statusMessage";
    }
    setState(() {});
  }

  String? _imageUrl;
  String? progressStr;

  ///post 文件上传
  fileUploadFunction() async {
    _imageUrl = null;
    setState(() {});
    //第一步
    Dio dio = Dio();

    String url = "http://192.168.1.24:8899/user/file/upload";

    //选择手机相册中的数据
    ImagePicker imagePicker = ImagePicker();
    //选择相册 中的图片
    XFile? imageFile = await imagePicker.pickImage(source: ImageSource.gallery);

    if (imageFile == null) {
      return;
    }

    //第二步 组合 数据
    FormData formData = FormData.fromMap({
      "uploadFile": await MultipartFile.fromFile(imageFile.path),
      "fileName": "测试了---"
    });

    //第三步 上传
    Response response = await dio.post(url, data: formData,
        onSendProgress: (int count, int total) {
      debugPrint('上传进度 $count  $total');
      setState(() {
        progressStr = "$count / $total";
      });
    });

    //第四步 获取结果
    int? statusCode = response.statusCode;
    String? statusMessage = response.statusMessage;
    if (statusCode != null && statusCode == 200) {
      dynamic responseData = response.data;
      if (responseData != null) {
        String code = responseData["code"];
        String msg = responseData["msg"];
        if (code == "OK") {
          dynamic itemData = responseData["data"];
          _imageUrl = itemData;
          debugPrint("图片上传成功：$itemData");
        } else {
          //请求失败的处理
          resultMessage = "请求失败 $code  $msg";
        }
      } else {
        resultMessage = "请求失败 无响应数据";
      }
    } else {
      //请求失败的处理
      resultMessage = "网络错误 $statusCode $statusMessage";
    }
    setState(() {});
  }

  /// 文件下载
  fileDownloadFunction() async {
    Dio dio = Dio();

    //下载地址
    String url = "";
    //保存的地址 图片 手机相册中
    String? savePath = await getPhoneLocalPath();
    if (savePath == null) {
      //提示用户
      return;
    }
    await dio.download(url, savePath,
        onReceiveProgress: (int current, int total) {
      debugPrint("下载进度 $current/$total");
      //刷新页面
    });
    //后续操作
  }

  Future<String?> getPhoneLocalPath() async {
    Directory? directory;
    if (Platform.isAndroid) {
      //获取的是android 的外部存储目录
      directory = await getExternalStorageDirectory();
    } else if (Platform.isIOS) {
      //获取的是 ios 的 Documents 或者  Downloads 目录
      directory = await getApplicationDocumentsDirectory();
    }
    if (directory == null) {
      return null;
    }
    return directory.path;
  }
}
